/******************************************************************************* * ***** BEGIN LICENSE BLOCK Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is the OpenCustomer CRM. * * The Initial Developer of the Original Code is Thomas Bader (Bader & Jene * Software-Ingenieurb�ro). Portions created by the Initial Developer are * Copyright (C) 2005 the Initial Developer. All Rights Reserved. * * Contributor(s): Thomas Bader <thomas.bader@bader-jene.de> * Felix Breske <felix.breske@bader-jene.de> * * ***** END LICENSE BLOCK ***** */ package org.opencustomer.connector.ldap.auth; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import javax.naming.Binding; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attributes; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchResult; import org.apache.log4j.Logger; import org.opencustomer.db.dao.calendar.CalendarDAO; import org.opencustomer.db.dao.system.LdapGroupDAO; import org.opencustomer.db.dao.system.RoleDAO; import org.opencustomer.db.dao.system.UserDAO; import org.opencustomer.db.vo.calendar.CalendarVO; import org.opencustomer.db.vo.system.LdapGroupVO; import org.opencustomer.db.vo.system.ProfileVO; import org.opencustomer.db.vo.system.UserVO; import org.opencustomer.framework.db.vo.EntityAccess; import org.opencustomer.framework.db.vo.EntityAccess.Access; import org.opencustomer.framework.util.SignatureUtility; import org.opencustomer.framework.util.password.PasswordGenerator; import org.opencustomer.util.configuration.SystemConfiguration; /** * Utilities for the LdapAuthenticator and the LdapSync. * @author fbreske * */ public class LdapUtil { private static final Logger log = Logger.getLogger(LdapUtil.class); private static LdapUtil instance; private Hashtable<String,String> env; private UserVO adminUser; public LdapUtil() { env = new Hashtable<String,String>(); env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); env.put("java.naming.factory.object", "com.sun.jndi.ldap.obj.LdapGroupFactory"); env.put("java.naming.factory.state", "com.sun.jndi.ldap.obj.LdapGroupFactory"); env.put(Context.PROVIDER_URL,"ldap://" + SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_SERVER) + ":" + SystemConfiguration.getInstance().getIntValue(SystemConfiguration.Key.LDAP_PORT) + "/" + SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_BASE_DN)); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_ADMIN_USER)); env.put(Context.SECURITY_CREDENTIALS, SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_ADMIN_PASSWORD)); adminUser = new UserDAO().getByUserName(SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_SYSTEM_USER)); } /** * * @return instance of LdapUtil */ public static LdapUtil getInstance() { if(instance == null) instance = new LdapUtil(); return instance; } /** * * @return HastTable with the settings for the ldap connection. (admin user and password) */ public Hashtable<String, String> getLdapEnvironment() { return env; } /** * This method creates a new user account with the given username. The user profile is set to the corresponding * LdapGroup. * @param username * @return the new UserVO or null if the user is no ldap user, or has no LdapGroup * @throws NamingException error on ladp connection */ public UserVO createUserFromLdap(String username) throws NamingException { UserVO user = new UserDAO().getByUserName(username); if(!LdapAuthenticator.getInstance().isLdapUser(username)) { if(log.isDebugEnabled()) log.debug("no ldap user for username: " + username); return null; } else if(user == null) { LdapGroupVO profile = getProfileForUser(username); if(profile != null) { if(log.isDebugEnabled()) log.debug("creating new user: " + username); InitialDirContext ctx = new InitialDirContext(env); Attributes attrs = ctx.getAttributes("uid=" + username + "," + SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_USER_PREFIX)); // Defaultwerte setzen user = new UserVO(); user.setUserName(attrs.get("Uid").get().toString()); user.setProfile(profile.getProfile()); user.setLocale(adminUser.getLocale()); user.setOwnerUser(adminUser.getId()); user.setOwnerGroup(adminUser.getId()); user.setAccessUser(Access.WRITE_SYSTEM); user.setAccessGroup(Access.READ); user.setAccessGlobal(Access.READ); user.setPassword(SignatureUtility.getInstance().createSignature(new PasswordGenerator().generate())); new UserDAO().insert(user,adminUser); CalendarVO calendar = new CalendarVO(); calendar.setUser(user); calendar.setAccessUser(EntityAccess.Access.WRITE_SYSTEM); calendar.setOwnerUser(user.getId()); calendar.setAccessGroup(EntityAccess.Access.NONE); calendar.setOwnerGroup(user.getProfile().getDefaultUsergroup().getId()); calendar.setAccessGlobal(EntityAccess.Access.NONE); new CalendarDAO().insert(calendar, user); } else { if(log.isDebugEnabled()) log.debug("user has no Ldap group: " + username); } } else if((user.getProfile().getRole().isAdmin() || (user.getProfile().getLdapGroup() == null))&& LdapAuthenticator.getInstance().isLdapUser(username)) { log.error("username conflict: " + username); } else { if(log.isDebugEnabled()) log.debug("user already exists: " + username); } return user; } /** * This method creates a new LdapGroup from the given Binding * @param binding the binding of the corresponding LdapGroup * @return the new LdapGroupVO * @throws NamingException error on ladp connection */ private LdapGroupVO createGroupFromLdap(String groupDN) throws NamingException { InitialDirContext ctx = new InitialDirContext(env); Attributes attrs = ctx.getAttributes(groupDN + "," + SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_GROUP_PREFIX),new String[]{"cn"}); LdapGroupVO ldapGroup = null; if(attrs.get("cn") != null) { String name = (String)attrs.get("cn").get(0); // TODO: what is this name for ldapGroup = new LdapGroupDAO().getByName(name); if(ldapGroup == null) { if(log.isDebugEnabled()) log.debug("creating new ldapGroup: " + name); ldapGroup = new LdapGroupVO(); ldapGroup.setName(groupDN); ldapGroup.setOwnerGroup(adminUser.getProfile().getDefaultUsergroup().getId()); ldapGroup.setOwnerUser(adminUser.getId()); ldapGroup.setPriority(new LdapGroupDAO().getAll().size()); ldapGroup.setAccessUser(Access.WRITE_SYSTEM); ldapGroup.setAccessGroup(Access.NONE); ldapGroup.setAccessGlobal(Access.NONE); ProfileVO profile = new ProfileVO(); profile.setAccessGlobal(Access.READ); profile.setAccessGroup(Access.READ); profile.setAccessUser(Access.WRITE_SYSTEM); profile.setIpPattern("*"); profile.setTimeLock(30); profile.setRole(new RoleDAO().getByName("User")); profile.setDefaultUsergroup(profile.getRole().getDefaultUsergroup()); profile.setOwnerUser(adminUser.getId()); profile.setOwnerGroup(adminUser.getProfile().getDefaultUsergroup().getId()); ldapGroup.setProfile(profile); new LdapGroupDAO().insert(ldapGroup,adminUser); } else { if(log.isDebugEnabled()) log.debug("ldapGroup already exists: " + name); } } return ldapGroup; } /** * This method searches for the actual LdapGroup for the user. * @param username username to search for * @return the prefered LdapGroupVO or null if the user has no LdapGroup * @throws NamingException error on ladp connection */ public LdapGroupVO getProfileForUser(String username) throws NamingException { String filter_groups = "(&(objectClass=groupOfUniqueNames)(uniqueMember={0}))"; String filter_user = "(&(objectClass=inetOrgPerson)(uid={0}))"; List<LdapGroupVO> ldapGroups = new ArrayList<LdapGroupVO>(); InitialDirContext ctx = new InitialDirContext(env); NamingEnumeration<SearchResult> enm = ctx.search(SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_USER_PREFIX),filter_user,new String[]{username},null); while(enm.hasMore()) { NamingEnumeration<SearchResult> enm2 = ctx.search(SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_GROUP_PREFIX),filter_groups,new String[]{enm.next().getNameInNamespace()},null); while(enm2.hasMore()) { LdapGroupVO tmpGroup = new LdapGroupDAO().getByDN(enm2.next().getName()); ldapGroups.add(tmpGroup); if(log.isDebugEnabled()) log.debug("found ldap group " + tmpGroup.getName() + " for user " + username); } } LdapGroupVO preferdGroup = null; for(LdapGroupVO tmp : ldapGroups) { if(preferdGroup == null || preferdGroup.getPriority() > tmp.getPriority()) preferdGroup = tmp; } if(log.isDebugEnabled()){ if(preferdGroup == null) log.debug("user has no group"); else log.debug("prefered group is: " + preferdGroup.getName()); } return preferdGroup; } /** * Test the ldap connection. * @return true if connection successfull, false if not */ public boolean testLdapConnection() { InitialDirContext ctx; try { ctx = new InitialDirContext(env); ctx.lookup(""); return true; } catch (NamingException e) { log.error("no ldap connection"); return false; } } /** * reads the oc ldap groups from ldap server * @return a list of group names (DN) * @throws NamingException */ public List<String> getLdapGroups() throws NamingException { List<String> groupList = new ArrayList<String>(); InitialDirContext ctx = new InitialDirContext(env); NamingEnumeration<Binding> enm = ctx.listBindings(SystemConfiguration.getInstance().getStringValue(SystemConfiguration.Key.LDAP_GROUP_PREFIX)); while (enm.hasMore()) { Binding b = enm.next(); groupList.add(b.getName()); } return groupList; } }